﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Room
{
    public class RCAISafeArea : RCAIBase
    {
        SafeZoneType safeZoneType;
        List<Vector2> areaData;
        //Vector2 prevPos;
        float timer0;
        float timer1;
        float recoverTime = 60f;
        RoomCharactor self;

        float hpRecoverPer = 0f;


        Dictionary<string, RoomCharactor> safePlayers = new Dictionary<string, RoomCharactor>();


        public RCAISafeArea(RoomCharactor owner)
            : base(owner)
        {
            type = AIType.SafeArea;
        }

        public void Init(List<Vector2> areaData, SafeZoneType safeZoneType)
        {
            this.areaData = areaData;
            this.safeZoneType = safeZoneType;
            this.inArea = false;
            //this.prevPos = Vector2.one * 10000f;
            string var0 = Dict.DictDataManager.Instance.tableGameConfigureDao.currentData.HpRecoveryPercent;
            var vars = var0.Split(new char[1] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
            recoverTime = float.Parse(vars[0]);
            hpRecoverPer = float.Parse(vars[1]);
            this.safePlayers.Clear();
        }

        GameObject hpEffectObj;

        private bool inArea;
        public bool InArea
        {
            get
            {
                return inArea;
            }
            set
            {
                if (inArea == false && value)
                {
                    BoxManager.CreatePopupTextBox(TableTextBlo.GetText("field_enter_safe_area"));
                    if (StaticData.fieldData.currentHp < 1f)
                    {
                        var hpObj = GameObjectPoolManager.Instance.Spawn(RoomField.particleRecoverHp, CommonMethod.GetAssetNameFromAssetBundleName(RoomField.particleRecoverHp));
                        var page = UI.PageManager.Instance.currentPage;
                        hpObj.transform.SetParent(page.transform);
                        hpObj.transform.localScale = Vector3.one;
                        hpObj.transform.localPosition = Vector3.zero;

                        hpObj.SetActive(true);

                        hpEffectObj = hpObj;

                        if (UIAutoSize.Instance.mySize == UIAutoSize.UISize.Size_16_9)
                        {

                        }
                        else if (UIAutoSize.Instance.mySize == UIAutoSize.UISize.Size_16_10)
                        {
                            hpObj.transform.localPosition = new Vector3(0, 10, 0);
                        }
                        else if (UIAutoSize.Instance.mySize == UIAutoSize.UISize.Size_3_2)
                        {
                            hpObj.transform.localPosition = new Vector3(0, 40, 0);
                        }
                        else if (UIAutoSize.Instance.mySize == UIAutoSize.UISize.Size_4_3)
                        {
                            hpObj.transform.localPosition = new Vector3(0, 70, 0);
                        }
                    }
                }

                else if (inArea && !value)
                {
                    BoxManager.CreatePopupTextBox(TableTextBlo.GetText("field_leave_safe_area"));

                    if (hpEffectObj != null)
                    {
                        GameObjectPoolManager.Instance.Unspawn(hpEffectObj);
                    }

                }
                inArea = value;
            }
        }

        public override void Tick()
        {
            this.self = owner.charactorManager.GetSelfCharactor();
            InArea = CheckInSafeArea(self);
            CheckOtherInSafeArea();
            RecoverySelf();
            //RecoveryOther();

            if (hpEffectObj != null && StaticData.fieldData.currentHp >= 1f)
            {
                GameObjectPoolManager.Instance.Unspawn(hpEffectObj);
            }
        }

        float checkTimer = 1;
        float checkCurTimer = 1;

        void CheckOtherInSafeArea()
        {
            checkCurTimer += Time.deltaTime;
            if (checkCurTimer >= checkTimer)
            {
                checkCurTimer = 0;
                safePlayers.Clear();

                foreach (var kvp in owner.charactorManager.GetCharactors())
                {
                    if (kvp.Value.type == CharactorType.OtherPlayer) //检测其他玩家
                    {
                        if (CheckInSafeArea(kvp.Value))
                        {
                            safePlayers[kvp.Key] = kvp.Value;
                        }
                    }
                }
            }
        }

        public bool CheckInSafeArea(RoomCharactor self)
        {
            if (self != null)
            {
                var selfPos = new Vector2(self.transform.position.x, self.transform.position.z);
                
                if (safeZoneType == SafeZoneType.Circle)
                {
                    var pos = areaData[0];
                    var r = areaData[1].x;

                    var dis = Vector2.Distance(selfPos, pos);

                    return dis <= r;
                }
                else if (safeZoneType == SafeZoneType.Rectangle)
                {
                    var pos0 = areaData[0];
                    var pos1 = areaData[1];

                    var xMin = pos0.x > pos1.x ? pos1.x : pos0.x;
                    var xMax = pos0.x > pos1.x ? pos0.x : pos1.x;

                    var yMin = pos0.y > pos1.y ? pos1.y : pos0.y;
                    var yMax = pos0.y > pos1.y ? pos0.y : pos1.y;

                    var x = selfPos.x;
                    var y = selfPos.y;

                    return xMin <= x && x <= xMax && yMin <= y && y <= yMax;
                }
                else if (safeZoneType == SafeZoneType.Triangle)
                {
                    var pos0 = areaData[0];
                    var pos1 = areaData[1];
                    var pos2 = areaData[2];

                    var a = new Vector3(pos0.x, 0, pos0.y);
                    var b = new Vector3(pos1.x, 0, pos1.y);
                    var c = new Vector3(pos2.x, 0, pos2.y);
                    var p = new Vector3(selfPos.x, 0, selfPos.y);

                    return PointInTriangle(a, b, c, p);
                }
            }

            return InArea;
        }

        bool SameSide(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
        {
            var AB = B - A;
            var AC = C - A;
            var AP = P - A;
            var v1 = Vector3.Cross(AB, AC);
            var v2 = Vector3.Cross(AB, AP);
            return Vector3.Dot(v1, v2) >= 0;
        }

        bool PointInTriangle(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
        {
            return SameSide(A, B, C, P) &&
                SameSide(B, C, A, P) &&
                SameSide(C, A, B, P);
        }


        void RecoverySelf()
        {
            if (InArea)
            {
                timer0 += Time.unscaledDeltaTime;
                if (timer0 >= recoverTime)
                {
                    bool succ = false;
                    StaticData.fieldData.AddHpPercent(hpRecoverPer, out succ);
                    self.ai.SetHp(StaticData.fieldData.currentHp);
                    UI.UIFieldRunMap.RefreshPage();
                    timer0 = 0f;


                    Debug.Log("[DEBUG] log current hp:" + StaticData.fieldData.currentHp);

                }
            }
            else
            {
                timer0 = 0f;//出去直接清零了
            }
        }

        void RecoveryOther()
        {
            timer1 += Time.unscaledDeltaTime;
            if (timer1 >= recoverTime)
            {
                timer1 = 0;
                foreach (var kvp in safePlayers)
                {
                    //var key = kvp.Key;
                    //var v = kvp.Value;
                    var playerId = long.Parse(kvp.Key);
                    if (StaticData.playerInfos.ContainsKey(playerId))
                    {
                        var curHp = (float)StaticData.playerInfos[playerId].info.playerSide.curHp;
                        curHp += hpRecoverPer;
                        curHp = Mathf.Clamp01(curHp);
                        StaticData.playerInfos[playerId].info.playerSide.curHp = curHp;

                        kvp.Value.ai.SetHp(curHp);
                    }
                }
            }
        }
    }
}
